<template>
  <tiny-skeleton v-if="!state.showPage" animated />
  <div v-else style="height: calc(100vh - 35px);">
    <tiny-split v-model="state.split1" >
      <template #left>
        <div class="bill-cls" style="width: 1230px;">
          <!--      表单-->
          <x-form v-model:api="fApi" v-model="formModel" v-model:rules="billRules" @mounted="formMounted" />
          <!--      底部按钮-->
          <billBottomBtn ref="bottomRef"
                         :billRules="billRules"
                         :infoBak="infoBak"
                         :model="formModel"
                         @refresh="refresh"
                         @toList="toList"
          />
        </div>
      </template>
      <template #right>
        <div class="ml5" >
          <billRightList ref="billListRef"   @openBill="openBill"  />
        </div>
      </template>
    </tiny-split>
  </div>
</template>
<script setup>
// 所有票据页面 组件
import tool from '@/utils/tool';
import bus from '@/store/bus';
import billRightList from '@/views/bills/billRightList.vue';
import { useGlobal } from '@/store/globalStore';
import codeBar from '@/lui/codeBar.vue';
import billBottomBtn from '@/views/bills/billBottomBtn.vue';
import { ref, onActivated, onDeactivated, computed, nextTick, watch, getCurrentInstance, onBeforeMount } from "vue";
import {useRouter} from "vue-router";
const global = useGlobal();
const instance = getCurrentInstance()
const { proxy } = getCurrentInstance()
const route = proxy.$route
const billListRef = ref()
const bottomRef = ref()
const infoBak = ref([])
const router = useRouter()
const fApi = ref({})
const formModel = ref({})
const billRules = ref([])
const defaultLines = ref(15) // 默认显示多少行
const currentRowIndex = ref() // 默认显示多少行
const state = ref({
  url: 'bill',
  hasFrame: false,
  split1: '1230px',
  showPage: false,
  whichPage: '',
  orgin: '',
})

const listRoute = ref('')
const pageOptions = ref({
  pageRule: {

  }
})
const toList = () => {
  if(listRoute.value){
    router.push({name: listRoute.value})
  }
  else{
    router.push({name: route.name+'s'})
  }
}
const getSystemInfo = async () => {
  await tool.post('bill/getSystemParams').then((ret) => {
    if (ret.stat) {
      global.systemParams = ret.data
    }
  })
}
const getStorage = async () => {
  await tool.post('common/dropdown', {cat: 'location'}).then((ret) => {
    global.storageList = ret.data;
  })
}
const getPageRule = async () => {
  pageOptions.value = await tool.getPageRule(state.value.whichPage)
  pageOptions.value.pageRule = new Function('_tool', '_app', '_whichPage', '_storage','_this', 'return ' + pageOptions.value.pageRule)(tool, instance.exposed, route.meta.routeId, storage.value, pageOptions.value);

  formModel.value.transType = tool.xe.toNumber(pageOptions.value.pageRule.transType);
  formModel.value.billType = pageOptions.value.pageRule.billType;
  formModel.value.transTypeName = pageOptions.value.pageRule.transTypeName;
  listRoute.value = typeof pageOptions.value.pageRule.listRoute === 'undefined'?'':pageOptions.value.pageRule.listRoute;

  formModel.value.billState = 'ready';
  billRules.value = pageOptions.value.pageRule.rule;
  let infos = []
  let infoModel = []
  for (let i = 0; i < pageOptions.value.pageRule.rule.length; i++) {
    if (pageOptions.value.pageRule.rule[i].field === 'infos') {
      infos = pageOptions.value.pageRule.rule[i].columns
      break
    }
  }
  let row = {}
  for (let i = 0; i < infos.length; i++) {
    row[infos[i].field] = ''
    if (infos[i].idField) {
      row[infos[i].idField] = 0
    }
  }
  for (let i = 0; i < defaultLines.value; i++) {
    infoModel.push(tool.xe.clone(row, true))
  }
  infoBak.value = tool.xe.clone(infoModel, true)
  formModel.value.infos = infoModel
  state.value.showPage = true
  initDataByQuery()

}
const initDataByQuery = () => {
  let query = tool.data.get('query')
  if (query) {
    setTimeout(() => {
      if (state.value.showPage) {
        openBill(query.billNo);
      } else {
        if (state.value.showPage) {
          openBill(query.billNo);
        } else {
          openBill(query.billNo);
        }
      }
      tool.data.remove('query');
    }, 200)
  }
}
const changeVal = ({val, cell}) => {
  let row = cell.row
  let column = cell.column
  let rowIndex = cell.rowIndex
  let transType = fApi.value.getValue('transType');
  let buId = fApi.value.getValue('buId');
  let field = column.property;
  if (field === 'invName') {
    if (!val) {
      for (let i in row) {
        if (i && i !== '_RID') {
          row[i] = null;
        }
      }
    }
    else {
      if (storage.value.length === 0) {
        return tool.err('还没有读取到仓库信息，请确认是否有仓库')
      }
      tool.post('bill/priceHist', {
        invId: row.invId,
        transType,
        buId,
      }).then((ret) => {
        if (ret.stat) {
          let data = ret.data;
          if (data) {
            row.spec = data.spec;
            row.calNum = data.spec; // 换算成最小单位的系数
            if (data.price) row.price = data.price;
            row.locationId = storage.value[0].id;
            row.locationName = storage.value[0].name;
            row.unit = data.unit;
            if (transType === 150601) {
              if (data.deduction) row.deduction = tool.xe.toNumber(data.deduction) === 0 ? '' : data.deduction;
            }

            fApi.value.exec('infos', 'moveCellToNext', {column, row, rowIndex})
          }
        }
      })
    }
  }
  if (field === 'unit') {
    row.calNum = val ? val.calNum : 0;
    if (row.spec !== row.calNum) {
      row.price = tool.xe.round(tool.divide(row.price, row.spec), 2);
    } else {
      row.price = tool.xe.round(tool.multiply(row.price, row.spec), 2);
    }
    fApi.value.exec('infos', 'moveCellToNext', {column, row, rowIndex})
  }
  if (field === 'locationName') {
    fApi.value.exec('infos', 'moveCellToNext', {column, row, rowIndex})
  }
  if (field === 'send') {
    if (!val) {
      return;
    }
    if (!row.invId) {
      row.send = '';
      return;
    }
    if (tool.xe.toNumber(val.id) === 0) {
      row.price = '';
      row.amount = '';
      row.deduction = '';
      row.sendId = '';
      row.send = '';
    } else {
      if (!val.id) return;
      if (!row.invId) return;
      if (!row.locationId) return;
      if (!row.locationName) return;
      tool.post('bill/getSendInfoById', {id: val.id}, false).then((ret) => {
        if (ret.stat) {
          let data = ret.data;
          let row1 = {
            invId: data.sendInvId,
            invName: data.sendInvName,
            unit: data.unit1,
            calNum: data.calNum,
            spec: data.spec,
            locationId: row.locationId,
            locationName: row.locationName,
            price: '',
            amount: '',
            deduction: '',
            send: '自赠',
            sendId: val.id,
            remark: '买' + data.buyQty + '赠' + data.sendQty+data.unit1,
            qty: tool.xe.round((data.sendQty * row.qty) / data.buyQty, 1),
          };
          row.send = '';
          row.sendId = '';
          let r = JSON.parse(JSON.stringify(row1));
          formModel.value.infos.splice(Number(rowIndex) + 1, 0, r);
        }
      });
    }
    fApi.value.exec('infos', 'moveCellToNext', {column, row, rowIndex})
  }
}
// 保存草稿
const formMounted = () => {
  bottomRef.value.setApi(fApi.value)
  nextTick(() => {
    setTimeout(() => {
      if(billListRef.value) {
        billListRef.value.setApi(fApi.value)
      }
    }, 200)
  })
}
const refresh = () => {
  billListRef.value.getList()
}
// 计算欠款
const calArrears = () => {
  if (formModel.value.transType === 153201) return;
  if (fApi.value && !tool.xe.isEmpty(fApi.value)) {
    if (!formModel.value.infos) return;
    let list = tool.xe.clone(formModel.value.infos, true)
    let ret = [];
    if (formModel.value.transType === 153403) {
      list.map((row) => {
        if (row.invId && row.invName && row.spec && row.calNum && row.unit) {
          ret.push(row);
        }
      });
    } else if (formModel.value.transType === 153404 || formModel.value.transType === 153405) {
      list.map((row) => {
        if (row.accId && row.amount) {
          ret.push(row);
        }
      });
    } else if (formModel.value.transType === 153401 || formModel.value.transType === 153402) {
      list.map((row) => {
        if (row.subjectId && row.amount) {
          ret.push(row);
        }
      });
    } else if (formModel.value.transType === 150603) {
      list.map((row) => {
        if (row.invId && row.invName && row.spec && row.locationId && row.calNum && row.unit) {
          row.amount = row.trans === '换入' ? -row.amount : row.amount;
          ret.push(row);
        }
      });
    } else {
      list.map((row) => {
        if (row.invId && row.invName && row.spec && row.locationId && row.calNum && row.unit) {
          ret.push(row);
        }
      });
    }
    let amount = tool.xe.sum(ret, 'amount');

    formModel.value.totalAmount = tool.xe.toFixed(amount, 2);
    let rpAmount = tool.xe.toNumber(formModel.value.rpAmount);
    let disAmount = tool.xe.toNumber(formModel.value.disAmount);
    let ysAmount = tool.xe.toNumber(formModel.value.ysAmount);
    let arrears = tool.minus(amount, rpAmount, disAmount, ysAmount);
    formModel.value.arrears = arrears ? tool.xe.toFixed(tool.xe.round(arrears, 2), 2) : '';
  }
}
const scanRet = (ret) => {
  state.value.orgin = ret.data ? ret.data.orgin : ''
  if (typeof ret.data.disAmount !== 'undefined' && tool.xe.toNumber(ret.data.disAmount) === 0) ret.data.disAmount = ''
  if (typeof ret.data.rpAmount !== 'undefined' && tool.xe.toNumber(ret.data.rpAmount) === 0) ret.data.rpAmount = ''
  if (typeof ret.data.ysAmount !== 'undefined' && tool.xe.toNumber(ret.data.ysAmount) === 0) ret.data.ysAmount = ''
  if (typeof ret.data.arrears !== 'undefined' && tool.xe.toNumber(ret.data.arrears) === 0) ret.data.arrears = ''
  if (ret.data.transType !== 153001 && ret.data.transType !== 153101) {
    ret.data.infos.map((row) => {
      row.amount = tool.xe.toNumber(row.amount) !== 0 ? tool.xe.toFixed(row.amount, 2) : '';
      row.deduction = tool.xe.toNumber(row.deduction) !== 0 ? tool.xe.toFixed(row.deduction, 2) : '';
      row.price = tool.xe.toNumber(row.price) !== 0 ? tool.xe.toFixed(row.price, 2) : '';
    })
  }
  let len = ret.data.infos.length
  if (len < 15) {
    for (let i = 0; i < 15 - len; i++) {
      ret.data.infos.push({})
    }
  }
  for (let i = 0; i < pageOptions.value.pageRule.rule.length; i++) {
    let r = pageOptions.value.pageRule.rule[i]
    if(r.int) {
      ret.data[r.field] = tool.xe.toNumber(ret.data[r.field]) !== 0?ret.data[r.field]:''
    }
    if(r.money) {
      ret.data[r.field] = tool.xe.toNumber(ret.data[r.field]) !== 0?tool.xe.toFixed(ret.data[r.field],2):''
    }
    if(r.float) {
      ret.data[r.field] = tool.xe.toNumber(ret.data[r.field]) !== 0?tool.xe.toFixed(ret.data[r.field],r.precision):''
    }
  }
  formModel.value = ret.data
}
const openBill = (billNo) => {
  if (!billNo) return;
  tool.post('bill/getDetailByNo', {billNo: billNo, transType: formModel.value.transType}, true).then((ret) => {
    if (ret.stat) {
      scanRet(ret);
    }
  })
}
const clear = () => {
  fApi.value.exec('hxList', 'setData', []);
  fApi.value.exec('billList', 'setData', []);
}
// 核销单中使用
const changeData = () => {
  let otherType = formModel.value.otherType
  let buId = formModel.value.buId
  if (otherType === '预收冲应收') {
    formModel.value.billType = 'YS2YS'
    fApi.value.mergeRule('buName', {props: {cat: 'customer'}});
    let rule = fApi.value.getRule('buName');
    let rule1 = fApi.value.getRule('l1');
    let rule2 = fApi.value.getRule('l2');
    rule1.title = '预收票据列表';
    rule2.title = '应收票据列表';
    rule.title = '客户';
  }
  if (otherType === '预付冲应付') {
    formModel.value.billType = 'YF2YF'
    fApi.value.mergeRule('buName', {props: {cat: 'provider'}});
    let rule = fApi.value.getRule('buName');
    let rule1 = fApi.value.getRule('l1');
    let rule2 = fApi.value.getRule('l2');
    rule1.title = '预付票据列表';
    rule2.title = '应付票据列表';
    rule.title = '供应商';
  }
  if (!otherType) {
    clear();
    return;
  }
  if (!buId) {
    clear();
    return;
  }
  tool.post('bill/getYsBillList', {buId: buId, otherType: otherType}).then((ret) => {
    if (ret.stat && ret.data) {
      fApi.value.exec('hxList', 'setData', ret.data.hxList);
      fApi.value.exec('billList', 'setData', ret.data.billList);
    } else {
      clear();
    }
  });
}
// 打印成功设置已打印

const insertRow = (i, r) => {
  formModel.value.infos.splice(Number(currentRowIndex.value) + i, 0, r);
}
// 单元格进入编辑
const editActived = ({row, column, rowIndex}) => {
  currentRowIndex.value = rowIndex
  let buId = fApi.value.getValue('buId');
  let field = column.property;
  let transType = fApi.value.getValue('transType')
  if (column.editor) {
    if (column.editor.attrs && field === 'invName') {
      column.editor.attrs.buId = buId;
      column.editor.attrs.invId = row.invId;
      column.editor.attrs.transType = transType;
    }
    if (column.editor.attrs && field === 'unit') {
      column.editor.attrs.invId = row.invId;
    }
    if (column.editor.attrs && field === 'send') {
      column.editor.attrs.qty = row.qty;
      column.editor.attrs.buId = buId;
      column.editor.attrs.invId = row.invId;
    }
  }
  if (field === 'amount') {
  }
}
// 单元格结束 编辑 计算行小计金额
const editClosed = ({row, column}) => {
  let billType = fApi.value.getValue('billType');
  let transType = fApi.value.getValue('transType');
  let field = column.property;
  let qty = tool.xe.toNumber(row.qty);
  let deduction = tool.xe.toNumber(row.deduction);
  let price = tool.xe.toNumber(row.price);
  switch (field) {
    case 'yhAmount': {
      let yhAmount = tool.xe.toNumber(row.yhAmount);
      if (row.srcTransType === 150602 || row.srcTransType === 150502) {
        row.yhAmount = yhAmount ? tool.xe.toFixed(-Math.abs(yhAmount), 2) : '';
      } else {
        row.yhAmount = yhAmount ? tool.xe.toFixed(yhAmount, 2) : '';
      }
    }
      break;
    case 'nowCheck': {
      let nowCheck = tool.xe.toNumber(row.nowCheck);
      if (row.srcTransType === 150602 || row.srcTransType === 150502) {
        row.nowCheck = nowCheck ? tool.xe.toFixed(-Math.abs(nowCheck), 2) : '';
      } else {
        row.nowCheck = nowCheck ? tool.xe.toFixed(nowCheck, 2) : '';
      }
    }
      break;
    case 'qty': {
      row.qty = qty ? qty : '';
      let am = tool.multiply(tool.minus(price, deduction), row.qty);
      row.amount = am ? tool.xe.toFixed(am, 2) : '';
    }
      break;
    case 'price': {
      row.price = price ? tool.xe.toFixed(tool.xe.round(price, 2), 2) : '';
      let am = tool.multiply(tool.minus(row.price, deduction), row.qty);
      row.amount = am ? tool.xe.toFixed(am, 2) : '';
    }
      break;
    case 'deduction': {
      row.deduction = deduction ? tool.xe.toFixed(tool.xe.round(deduction, 2), 2) : '';
      let am = tool.multiply(tool.minus(price, row.deduction), row.qty);
      row.amount = am ? tool.xe.toFixed(am, 2) : '';
    }
      break;
    case 'amount': {
      let amount = tool.xe.toNumber(row.amount);
      row.amount = amount ? tool.xe.toFixed(tool.xe.round(amount, 2), 2) : '';
      let p = qty ? tool.add(tool.xe.round(tool.divide(row.amount, qty), 2), deduction) : 0;
      row.price = p ? Math.abs(p) : '';
    }
      break;
    case 'invName': {
      if (!row.invName) {
        row.price = ''
        row.amount = ''
        row.spec = ''
        row.unit = ''
        row.remark = ''
        row.qty = ''
        row.locationId = 0
        row.locationName = ''
        row.send = ''
        if (transType === 150601) {
          row.deduction = ''
        }
      } else {
      }
    }
      break;
    case 'locationName': {
      //
    }
      break;
    case 'send': {
      if (row.send) {
        if (tool.xe.toNumber(row.send) !== 0) {
          row.send = ''
        }
      }
    }
      break;
  }
  if (billType === 'RECEIPT' || billType === 'PAYMENT') {
    if (row.billId) {
      nextTick(() => {
        row.yhAmount = tool.xe.toNumber(row.yhAmount);
        row.yeAmount = tool.minus(row.leftAmount, row.nowCheck, row.yhAmount);
      });
    }
  }
}
const getEditList = (data) => {
  let list;
  let ty = fApi.value ? fApi.value.getValue('transType') : '';
  if (ty === 150603) {
    let ls = tool.xe.clone(data, true);
    ls.map((row) => {
      row.qty = row.trans === '换入' ? -row.qty : row.qty;
      row.amount = row.trans === '换入' ? -row.amount : row.amount;
    });
    list = ls;
  } else {
    list = tool.xe.clone(data, true);
  }
  return list;
}
// 单元格下拉变化
const storage = computed(() => {
  return global.storageList;
})

const printSuc = () => {
  formModel.value.printNo = 1
}

const clickMore = (row, type) => {
  if(type === 'good') {
    let buId = fApi.value.getValue('buId')
    if (!buId) return tool.err('请选择供应商')
    let options = {
      title: '选择商品',
      width: 1000,
      height: 700,
      mounted: (api) => {
        setTimeout(() => {
          options.getData(api)
        }, 50)
      },
      rules: [
        {
          field: 'jtab',title:' ',com:'JTab',list:[{id:'商品',name: '商品'},{id:'近期交易',name: '近期交易'}],
          defaultValue: '近期交易',width: 260,inject: true,
          events: {
            change: (api, val) => {
              options.getData(api)
            }
          }
        },
        {field: 'invName', title:'商品名称',com: 'JInput', width: 260},
        {
          field:'',title:' ',com: 'JButton',text: '查询',width: 120,type: 'info',icon:'search',inject: true,
          events: {
            click: (api) => {
              options.getData(api)
            }
          }
        },
        {
          field: 'grid',title:'',com: 'JGrid',width: 950,height: 600,
          columns: [
            { type: 'index', width: 40 },
            { type: 'selection', width: 40, align: 'center' },
            { field: 'name', title: '名称', width: 300, align: 'left', filter: true, sortable: true ,visible: true},
            { field: 'unit', title: '单位', width: 80, align: 'center',visible: true },
            { field: 'spec', title: '规格', width: 80, align: 'center' ,visible: true},
            { field: 'price', title: '价格', width: 80, align: 'right', formatter: 'formatMoney' ,visible: true},
            { field: 'deduction', title: '返利', width: 80, align: 'center', formatter: 'formatMoney',visible: true },
            { field: 'leftQty', title: '库存', width: 80, align: 'center', formatter: 'formatQty', sortable: true ,visible: true},
            { field: 'qty', title: '本次数量', width: 120, align: 'right', editor: 'JInput' ,visible: true},
          ]
        }
      ],
      btns: [
        {
          name: '选中',
          click: (api, close) => {
            let list = api.exec('grid', 'getSelect')
            if(list.length === 0) return tool.err('没有选择条目')
            api.exec('grid','clearActived')
            moreSelect(list, row.rowIndex)
            api.exec('grid','clearSelection')
          }
        },
        {
          name: '选中并关闭',
          click: (api, close) => {
            let list = api.exec('grid', 'getSelect')
            if(list.length === 0) return tool.err('没有选择条目')
            api.exec('grid','clearActived')
            moreSelect(list, row.rowIndex)
            setTimeout(() => {
              close()
            }, 10)
          }
        },
        {
          name: '关闭',
          click: (api, close) => {
            close()
          }
        },
      ],
      getData: (api) => {
        state.value.loading = true;
        setTimeout(() => {
          state.value.loading = false;
        }, 5000);
        tool
            .post('dropdown/invList', {
              buId: fApi.value.getValue('buId'),
              transType: fApi.value.getValue('transType'),
              keyWord: api.getValue('invName'),
              checkedVal: api.getValue('jtab'),
              currentPage: 1,
              pageSize: 100,
              cat: 'invList',
            }, true)
            .then((ret) => {
              api.exec('grid', 'setData', ret.data.list)
              state.value.total = ret.data.total;
              state.value.loading = false;
            })
      }
    }
    tool.editor(options)
  }
}
const moreSelect = (ret, rowIndex) => {
  let location = global.storageList;
  if (!location || location.length === 0) return tool.err('没有仓库');
  let infos = []
  for (let i = 0; i < ret.length; i++) {
    let data = ret[i];
    let r = {
      invId: data.id,
      invName: data.name,
      unit: data.unit,
      calNum: data.spec,
      spec: data.spec,
      locationId: location[0].id,
      locationName: location[0].name,
      price: data.price ? tool.xe.toFixed(data.price, 2) : '',
      amount: '',
      deduction: data.deduction ? tool.xe.toNumber(data.deduction) : '',
      send: '',
      sendId: '',
      remark: '',
      qty: data.qty ? tool.xe.toNumber(data.qty) : '',
    };
    let amount = tool.xe.multiply(r.qty, tool.xe.subtract(r.price, r.deduction));
    r.amount = amount ? tool.xe.toFixed(amount, 2) : '';
    let row = Object.assign({}, r)
    infos.push(row)
  }
  if(infos.length > 0) {
    let grid = tool.xe.clone(fApi.value.getValue('infos'), true)
    let new_infos = []
    grid[rowIndex] = infos[0]

    infos.splice(0, 1)

    for (let i = 0; i < grid.length; i++) {
      if(i <= rowIndex) {
        new_infos.push(grid[i])
      }
    }
    for (let i = 0; i < infos.length; i++) {
      new_infos.push(infos[i])
    }
    for (let i = 0; i < grid.length; i++) {
      if(i > rowIndex) {
        new_infos.push(grid[i])
      }
    }
    fApi.value.setValue('infos', new_infos)
  }
}

watch(() => formModel, () => {
  if (fApi.value && !tool.xe.isEmpty(fApi.value)) {
    if (formModel.value.billState !== 'ready' && formModel.value.billState !== 'draft') {
      fApi.value.disabled(true);
    } else {
      fApi.value.disabled(false);
    }
  }
  nextTick(() => {
    calArrears();
  })
}, {deep: true})
onBeforeMount(async () => {
  state.value.whichPage = route.meta.routeId
  await getStorage()
  await getSystemInfo()
  await getPageRule()
})
onActivated(() => {
  bus.$on('BillScan', scanRet)
  bus.$on('printSuc', printSuc)
  initDataByQuery()
})
onDeactivated(() => {
  bus.$off('BillScan', scanRet)
  bus.$off('printSuc', printSuc)
})

defineExpose({editClosed, editActived, changeVal, insertRow, clickMore })

</script>

<style lang="scss">
.bill-cls {
  height: 100%;
  padding: 10px;
  .tiny-grid-body__column:not(.col__index) {
    .tiny-grid-cell {
      color: #2b85e4 !important;
    }
  }
}


</style>